
import os
import shutil

import threading
from glob import glob
from common.utils import *


def get_plc_get_code(max_code = 7000):
    time000 = time.time()
    def plc_get_code():
        nonlocal time000
        time00011 = time.time()
        code = int((time00011-time000)*1000)
        if code>max_code:
            time000 = time00011
        return code

    return plc_get_code

def mymovefile(srcfile, dstpath):                       # 移动函数
    if not os.path.isfile(srcfile):
        print("%s not exist!" % (srcfile))
    else:
        fpath, fname = os.path.split(srcfile)             # 分离文件名和路径
        if not os.path.exists(dstpath):
            os.makedirs(dstpath)                       # 创建路径
        shutil.move(srcfile, dstpath + fname)          # 移动文件
        #print("move %s -> %s" % (srcfile, dstpath + fname))

def move_fns(fns, dpath, product):
    mkdir(dpath)
    out = []
    for sfn in fns:
        fpath, fname = os.path.split(sfn)
        fname1 = fname.split('_')
        ii = 5
        for i in range(len(fname1)):
            if len(fname1[i])>len(fname1[ii]):
                ii = i
        for i in range(len(fname1)):
            if 'NOREAD' in fname1[i]:
                ii = i
        fname1[ii] = product
        fname = '_'.join(fname1)
        dfn = f'{dpath}/{fname}'
        try:
            shutil.move(sfn, dfn)          # 移动文件
            out.append(dfn)
        except Exception as e:
            #print(e)
            pass

    return out
    
def test_mymovefile():
    src_dir = './'
    dst_dir = './move/'                                    # 目的路径记得加斜杠
    src_file_list = glob(src_dir + '*')                    # glob获得路径下所有文件，可根据需要修改
    for srcfile in src_file_list:
        mymovefile(srcfile, dst_dir)                       # 移动文件


class SafeCam(): #
    def __init__(self, cls, ip0 = None, triggermode='off', frame_callback=None):
        self.ip0 = None
        self.cam = None
        self.cls = cls # 相机句柄
        if ip0 is not None:
            self.open(ip0, triggermode, frame_callback) # 打开相机，
    
    def open(self, ip0, triggermode='off', frame_callback=None):
        if ip0 is not None:
            self.ip0 = ip0
            self.triggermode = triggermode
            self.frame_callback = frame_callback
            if frame_callback is None:
                self.cam = self.cls(ip0)
            else:
                self.cam = self.cls(ip0, triggermode, frame_callback)
            return 1

        return 0

    def close(self):
        if self.cam is not None:
            self.cam.close()
        return 0

    def getFrame(self):
        im = None
        for i in range(100):
            im = self.cam.getFrame()
            if im is not None:
                return im
        #if random.random()>0.5:
        #    im = None
        if im is None:
            print('SafeCam: cam reopen')
            self.close()
            self.cam = None
            self.open(self.ip0, self.triggermode, self.frame_callback)
            im = self.cam.getFrame()
        
        return im

def softcam_work_thd(ss):
    # 告知PLC CAM处于READY状态可以接受数据
    while ss.running:
        #print(f'cam_ready {i}')
        #ss.qq.put(1)
        try:
            img = ss.cam.getFrame()
            if ss.call_back is not None:
                ss.call_back(img)
            while ss.qq.qsize()>1:
                img1 = ss.qq.get()
            ss.qq.put(img)
        except Exception as e:
            #i = random.randint(0, 1000) % 2
            print(f'softcam_work_thd err {str(e)}')
            continue

    return 0

class SoftCam:
    def __init__(self, cam, call_back=None) -> None:
        self.cam = cam
        self.running = False
        self.thread_work = None
        self.call_back = call_back
        self.qq = queue.Queue()
        self.start()
    
    def __del__(self):
        self.stop()

    def getFrame(self):
        t0 = time.time()
        #while self.qq.qsize()>1:
        #    img = self.qq.get()
        img = self.qq.get()
        if 0:
            tt = time.time()-t0
            kk = 5
            if tt<kk:
                time.sleep((kk-tt)/1000)
        return img

    def start(self, qq=None):
        if self.thread_work is None:
            self.running = True
            self.thread_work = threading.Thread(target=softcam_work_thd, args=(self,))
            self.thread_work.start()

    def stop(self):
        if self.thread_work is not None:
            self.running = False
            self.qq.put(None)
            self.thread_work.join()
            self.thread_work = None
        self.qq.put(None)


    def close(self):
        self.stop()


def softtrigercam_work_thd(ss):
    # 告知PLC CAM处于READY状态可以接受数据
    while ss.running:
        #print(f'cam_ready {i}')
        #ss.qq.put(1)
        try:
            t0 = time.time()
            img = ss.cam.getFrame()
            if img is not None:
                if ss.callback is not None:
                    ss.callback(img)
            
            t1 = time.time()
            tt = t1-t0
            kk = 1/bound(ss.fps, 1, 20)
            if tt<kk:
                time.sleep(kk-tt)
        except Exception as e:
            #i = random.randint(0, 1000) % 2
            print(f'softtrigercam_work_thd err {str(e)}')
            continue


    return 0

class SoftTrigerCam:
    def __init__(self, cam, callback=None, fps=10) -> None:
        self.cam = cam
        self.fps = fps
        self.running = False
        self.callback = callback
        self.thread_work = None
        self.start()
    
    def __del__(self):
        self.stop()

    def start(self, qq=None):
        if self.thread_work is None:
            self.running = True
            self.thread_work = threading.Thread(target=softtrigercam_work_thd, args=(self,))
            self.thread_work.start()

    def stop(self):
        if self.thread_work is not None:
            self.running = False
            self.qq.put(None)
            self.thread_work.join()
            self.thread_work = None
        self.qq.put(None)


    def close(self):
        self.stop()

def get_callback(index, qq):
    def cam_callback(img):
        qq.put([index, img])
        return 0
    
    return cam_callback

def get_callback_hard(index, qq):
    def cam_callback(img):
        qq.put([index, img])
        return 0
    
    return cam_callback

def create_cam(cls, ip0, index, qq, fps=10, callback=None, callback_hard=None):
    #triggermode='off', 
    if fps>0:
        if callback is None:
            callback = get_callback(index, qq)
        cam = SafeCam(cls, ip0, 'off', None)
        cam = SoftTrigerCam(cam, callback, fps)
    else:
        if callback_hard is None:
            callback_hard = get_callback_hard(index, qq)
        cam = SafeCam(cls, ip0, 'hard', callback_hard)

    return cam

# 终止进程
def kill_process(pro_id):
    # if len(self.pro_name):
    #     # 根据进程名 kill 进程
    #     cmd_name = f'taskkill /f /im {self.pro_name}'
    #     os.system(cmd_name)
    for pid in pro_id:
        if pid > 0:
            try:
                print(f"kill process pid: {pid}")
                cmd_id = f'taskkill /f /pid {pid}'
                os.system(cmd_id)
                break  # 子线程 kill 掉就可以了
            except Exception as e:
                print(f"error: kill_process:{e}")


def baojin(code='code'):
    from midea_common.test_playwav import mp4play
    mp4play(code)

def test_SafeMVSCam():
    import MVSCam
    ips = [201+i for i in range(3)]
    cams = [SafeCam(MVSCam.MVSCam, str(ips[i])) for i in range(len(ips))]
    for i in range(1000):
        ims = [cams[i].getFrame() for i in range(len(ips))]
        ims = [cv2.resize(im, (640, 480)) if im is not None else None for im in ims]
        [cv2.imshow(f'im{i}', ims[i]) for i in range(len(ips)) if ims[i] is not None]
        print(i)
        cv2.waitKey(100)

    #cam.stop()
    return 0

def livefile(id=0):
    fnfn = f'D:\~live_{str(id)}.txt'
    if not os.path.exists(fnfn):
        with open(fnfn, 'w') as f:
            f.write(str(1))

if __name__ == "__main__":
    test_SafeMVSCam()
    del_last_img()
    baojin()
    test_mymovefile()
    # cv2.destroyAllWindows()
